/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xenon3d.scene;

/**
 * NodeComponent is a common superclass for all scene graph node component
 * objects such as: Geometry, Appearance, Material, Texture, etc.
 * 
 * @author Volker Everts
 * @version: 0.1 - 04.11.2011: Created
 */
public class NodeComponent extends SceneGraphObject {
    
    // <editor-fold defaultstate="collapsed" desc=" Constant Attributes ">
    
    /** The error message "Illegal Live Reference Count". */
    static final String ERR_LIVE_REF_COUNT = "Illegal Live Reference Count";
    
    /** The error message "Illegal Compiled Reference Count". */
    static final String ERR_COMP_REF_COUNT = "Illegal Compiled Reference Count";
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc=" Private Fields ">
    
    /** The live reference count for this NodeComponent. */
    int liveRef;
    
    /** The compiled reference count for this NodeComponent. */
    int compRef;
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc=" Initialization ">
    
    /**
     * Creates a new NodeComponent.
     */
    protected NodeComponent() {}
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc=" Public Properties ">
    
    @Override
    public boolean isLive() {
        return liveRef > 0;
    }
    
    @Override
    public boolean isCompiled() {
        return compRef > 0;
    }
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc=" Package Private Methods ">
    
    /**
     * Notifies this NodeComponent that it was added to a node's list of
     * components.
     */
    void addNotify(SceneGraphObject obj) {
        if (obj.isLive()) liveRef++;
        if (obj.isCompiled()) compRef++;
    }
    
    /**
     * Notifies this NodeComponent that it was removed from a node's list of
     * components.
     */
    void removeNotify(SceneGraphObject obj) {
        if (obj.isLive()) liveRef--;
        if (obj.isCompiled()) compRef--;
        if (liveRef < 0) throw new IllegalSceneGraphException(ERR_LIVE_REF_COUNT);
        if (compRef < 0) throw new IllegalSceneGraphException(ERR_COMP_REF_COUNT);
    }
    
    @Override
    boolean isLiveOrCompiled() {
        return liveRef + compRef > 0;
    }
    
    @Override
    void checkCapability(Capability cap) {
        if (liveRef + compRef > 0) {
            if (!caps.contains(cap)) throw new CapabilityNotSetException(cap.toString());
        }
    }

    @Override
    void setLive() {
        liveRef++;
    }

    @Override
    void clearLive() {
        liveRef--;
        if (liveRef < 0) throw new IllegalStateException(ERR_LIVE_REF_COUNT);
    }
    
    @Override
    void setCompiled() {
        compRef++;
    }

    @Override
    void clearCompiled() {
        compRef--;
        if (compRef < 0) throw new IllegalStateException(ERR_COMP_REF_COUNT);
    }

    // </editor-fold>

} // end class NodeComponent